;(function () {
	function MJFullPage(option = {}) {
    var noop = function() {}
    this.id = option.id || '';
    this.animateEnd = option.animateEnd || noop;
    this.slideEnd = option.slideEnd || noop;
    this.$parent = $("#" + this.id);
    this.$pages = this.$parent.children('.section');
    this.height = parseFloat($(window).height());

    // init idx
    this.idx = 0;
    this.prevIdx = NaN;
    this.nextIdx = 1;

    this.init();
    this.toPage(this.idx);
    this.leavePage(this.nextIdx);

    var self = this;

    this.$parent.on("touchstart", function(event) {
      self.touchstartHandler.call(self, event);
    });
    this.$parent.on("touchmove", function(event) {
      self.touchmoveHandler.call(self, event);
    });
    this.$parent.on("touchend", function(event) {
      self.touchendHandler.call(self, event);
    });

    // 兼容PC端, 添加鼠标滚轮事件
    $(window).on("mousewheel", function(event) {
      event.preventDefault();
      var direct;
      direct = event.deltaY > 0 ? 1 : -1;
      if (direct === 1) {
        self.goNext();
      } else if (direct === -1) {
        self.goPrev();
      }
    })

    // 屏幕尺寸变化的时候重新获取高度并执行初始化方法(包括手机屏幕方向改变)
    $(window).resize(function() {
      self.height = parseFloat($(window).height());
      self.init;
    });
	}

  // 初始化方法, 遍历每一页并设置初始位置
	MJFullPage.prototype.init = function() {
    var self = this;
    this.$pages.each(function() {
      $(this).css("-webkit-transform", "translate3d(0," + self.height + "px,0)");
    });
    this.$pages.eq(0).css("-webkit-transform", "translate3d(0,0,0)");
	}

	MJFullPage.prototype.touchstartHandler = function(event) {
    if (event.cancelable) {
      if (!event.defaultPrevented) {
        event.preventDefault();
      }
    }

    var finger = event.touches[0];
    this.startY = finger.clientY;

    this.$pages.eq(this.idx).css("-webkit-transition", "none");
    this.$pages.eq(this.nextIdx).css("-webkit-transition", "none");
    this.$pages.eq(this.prevIdx).css("-webkit-transition", "none");

    this.$pages.eq(this.idx).css("-webkit-transform", "translate3d(0," + 0 + "px,0)");
    this.$pages.eq(this.prevIdx).css("-webkit-transform", "translate3d(0," + -this.height + "px,0)");
    this.$pages.eq(this.nextIdx).css("-webkit-transform", "translate3d(0," + this.height + "px,0)");

	}

	MJFullPage.prototype.touchmoveHandler = function(event) {
    if (event.cancelable) {
      if (!event.defaultPrevented) {
        event.preventDefault();
      }
    }
    
    var finger = event.touches[0];
    this.dy = finger.clientY - this.startY;
    if (this.idx == 0 && this.dy > 0) {
      return;
    } else if (this.idx == this.$pages.length - 1 && this.dy < 0) {
      return;
    }
    this.leavePage(this.idx);

    if (this.dy < 0) {
      this.$pages.eq(this.nextIdx).css("-webkit-transform", "translate3d(0," + (this.height + this.dy) + "px,0)");
      this.$pages.eq(this.idx).css("-webkit-transform", "translate3d(0," + (this.dy) + "px,0)");
    } else if (this.dy > 0) {
      this.$pages.eq(this.prevIdx).css("-webkit-transform", "translate3d(0," + (-this.height + this.dy) + "px,0)");
      this.$pages.eq(this.idx).css("-webkit-transform", "translate3d(0," + (this.dy) + "px,0)");
    }

	}

	MJFullPage.prototype.touchendHandler = function(event) {
    if (this.dy < -this.height / 6) {
      this.goNext();
      this.leavePage(this.nextIdx);
    } else if(this.dy > this.height / 6) {
      this.goPrev();
      this.leavePage(this.prevIdx);
    } else {
      this.goCurrent();
    }
  }
  
  MJFullPage.prototype.goPrev = function() {
    if (this.idx === 0) {
      return;
    }
    this.$pages.eq(this.idx).css("-webkit-transition", "-webkit-transform 0.5s ease 0s");
    this.$pages.eq(this.prevIdx).css("-webkit-transition", "-webkit-transform 0.5s ease 0s");
    this.$pages.eq(this.prevIdx).css("-webkit-transform", "translate3d(0," + 0 + "px,0)");
    this.$pages.eq(this.idx).css("-webkit-transform", "translate3d(0," + this.height + "px,0)");

    this.nextIdx = this.idx;
    this.idx = this.prevIdx;
    this.prevIdx--;
    if (this.prevIdx < 0) {
      this.prevIdx = this.$pages.length - 1;
    }
    this.leavePage(this.nextIdx);
    this.toPage(this.idx);
  }

  MJFullPage.prototype.goNext = function() {
    if (this.idx == this.$pages.length - 1) {
      this.slideEnd();
      return;
    }
    this.$pages.eq(this.idx).css("-webkit-transition", "-webkit-transform 0.5s ease 0s");
    this.$pages.eq(this.nextIdx).css("-webkit-transition", "-webkit-transform 0.5s ease 0s");
    this.$pages.eq(this.nextIdx).css("-webkit-transform", "translate3d(0," + 0 + "px,0)");
    this.$pages.eq(this.idx).css("-webkit-transform", "translate3d(0," + -this.height + "px,0)");

    this.prevIdx = this.idx;
    this.idx = this.nextIdx;
    this.nextIdx++;
    if (this.nextIdx > this.$pages.length - 1) {
      this.nextIdx = 0;
    }
    this.leavePage(this.prevIdx);
    this.toPage(this.idx);
  }

  MJFullPage.prototype.goCurrent = function() {
    this.$pages.eq(this.idx).css("-webkit-transition", "-webkit-transform 0.5s ease 0s");
    this.$pages.eq(this.idx).css("-webkit-transform", "translate3d(0," + 0 + "px,0)");
    this.$pages.eq(this.prevIdx).css("-webkit-transition", "-webkit-transform 0.5s ease 0s");
    this.$pages.eq(this.prevIdx).css("-webkit-transform", "translate3d(0," + -this.height + "px,0)");
    this.$pages.eq(this.nextIdx).css("-webkit-transition", "-webkit-transform 0.5s ease 0s");
    this.$pages.eq(this.nextIdx).css("-webkit-transform", "translate3d(0," + this.height + "px,0)");
    this.toPage(this.idx);
  }

	MJFullPage.prototype.leavePage = function(idx) {
    this.$pages.eq(idx).find('.animated').each(function() {
      var delay = $(this).attr('delay') || 0;
      var self = $(this);
      setTimeout(function() {
        var showClass = self.data('show');
        var hideClass = self.data('hide');
        if (self.hasClass(hideClass)) {
          return;
        }
        hideClass && (self.addClass(hideClass));
        showClass && (self.removeClass(showClass));
      }, delay);
    })
	}

	MJFullPage.prototype.toPage = function(idx) {
    this.$pages.eq(idx).find('.animated').each(function() {
      var delay = $(this).attr('delay') || 0;
      var self = $(this);
      setTimeout(function() {
        var showClass = self.data('show');
        var hideClass = self.data('hide');
        if (self.hasClass(showClass)) {
          return;
        }
        showClass && (self.addClass(showClass));
        hideClass && (self.removeClass(hideClass));
      }, delay);
    })
	}

	window.MJFullPage = MJFullPage;
})();